package com.link.base.base.order.controller;

import com.link.base.base.enterprise.model.Enterprise;
import com.link.base.user.model.CoreUser;
import com.link.base.base.accnt.dao.mybatis.mapper.AccountMapper;
import com.link.base.base.accnt.dao.mybatis.mapper.AcctAddressMapper;
import com.link.base.base.accnt.model.Account;
import com.link.base.base.accnt.model.AcctAddress;
import com.link.base.base.order.model.OrderImpExp;
import com.link.base.base.order.model.SaleOrder;
import com.link.base.base.order.model.SaleOrderItem;
import com.link.base.base.order.service.SaleOrderItemService;
import com.link.base.base.order.service.SaleOrderService;
import com.link.base.base.product.dao.mybatis.mapper.ProductMapper;
import com.link.base.base.product.model.Product;
import com.link.core.basic.controller.BasicController;
import com.link.core.basic.controller.BasicControllerException;
import com.link.core.basic.model.BasicModel;
import com.link.core.basic.query.Filter;
import com.link.core.basic.query.QueryParams;
import com.link.core.basic.service.BasicServiceException;
import com.link.core.basic.service.KeyGenerateService;
import com.link.core.basic.service.ServiceException;
import com.link.core.modules.excel.HssfExcelHelper;
import com.link.core.modules.excel.XssfExcelHelper;
import com.link.core.util.DateUtil;
import com.link.core.util.UserUtil;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.util.*;

/**
 * @author unknown
 * @date unknown
 * @comments 定单头详情请求处理
 */
@Controller
@RequestMapping("/link/saleorderHeadItem")
public class SaleOrderHeadAndItemController extends BasicController<OrderImpExp> {
    private static final Logger logger = LogManager.getLogger(SaleOrderHeadAndItemController.class);
    @Resource
    protected KeyGenerateService keyGenerateService;
    @Resource
    private SaleOrderItemService saleOrderItemService;
    @Resource
    private SaleOrderService saleOrderService;
    @Resource
    private AccountMapper accountMapper;

    @Resource
    private AcctAddressMapper acctAddressMapper;

    @Resource
    private ProductMapper productMapper;


    /**
     * 导入Excel
     */
    @Override
    public void beforReadExcel(OrderImpExp entity, QueryParams qps, HttpServletRequest request) throws Exception {
        //导入头：订单编号、收货地址、期望发货日期、头备注
        //导入行：商品编码、商品名称、数量、
        // 拼接头行字段，与EXCEL导入数据对应
        qps.setAttr1("orderNo,addr,expectDate,comments,prodCode,prodName,qty");
        //设置是否有标题
        qps.setAttr3("true");
        //设置头行导入模式
        qps.setAttr4("true");
        entity.setStatus("新建");
        entity.setOrderType("销售订单");
    }

    /**
     * 导入前的检测操作
     *
     * @param list
     * @param request
     * @throws Exception
     */
    @Override
    public void importCheckExcel(List<OrderImpExp> list, HttpServletRequest request) throws Exception {
        String errorMessage = "";
        //存放地址错误信息的excel索引
        List<Integer> addrList = new ArrayList<Integer>();
        //存放编号错误信息的excel索引
        List<Integer> codeList = new ArrayList<Integer>();
        //存放产品名错误信息的excel索引
        List<Integer> nameList = new ArrayList<Integer>();
        //存放期望日期格式错误的excel索引
        List<Integer> dateList = new ArrayList<Integer>();
        CoreUser user = UserUtil.getUser();
        Enterprise enterprise = (Enterprise) (request.getSession().getAttribute("UserEnterpriseContext"));
        String multiPriceList = enterprise.getIsMultiPriceList();
        for (int i = 0; i < list.size(); i++) {
            OrderImpExp record = list.get(i);
            System.err.println("期望日期：" + record.getExpectDate());
            if (!DateUtil.isDayFormatString(record.getExpectDate())) {
                dateList.add(i + 2);
            }
            //根据地址名找客户地址ID
            QueryParams qps = new QueryParams();
            qps.addFilter(new Filter("fullAddr", String.valueOf(record.getAddr())));
            qps.addFilter(new Filter("acctId", String.valueOf(user.getAcctId())));
            qps.setPageFlag(false);
            AcctAddress acctAddr = (AcctAddress) BasicModel.transformClass(AcctAddress.class, qps);
            List<AcctAddress> acctAddrList = acctAddressMapper.queryByExamplePage(acctAddr);
            if (acctAddrList.size() == 0) {
                addrList.add(i + 2);
                //throw new Exception("地址信息有误！");
            }
            //根据产品编码或商品名称找产品ID
            if (!"".equals(record.getProdCode())) {
                Product product = new Product();
                product.setPageFlag(false);
                product.setProdCode(record.getProdCode());
                product.setAcctId(user.getAcctId());

                product.setAttr7(multiPriceList);

                List<Product> prodList = productMapper.queryProdWithAcctPriceByCodeOrName(product);
                if (prodList.size() == 0) {
                    //找到一个或多个产品信息时取第一条生成行，没找到忽略当条
                    //throw new Exception("产品编码信息有误！");
                    codeList.add(i + 2);
                }
            } else if (!"".equals(record.getProdName())) {
                Product product = new Product();
                product.setPageFlag(false);
                product.setProdName(record.getProdName());
                product.setAcctId(user.getAcctId());

                product.setAttr7(multiPriceList);

                List<Product> prodList = productMapper.queryProdWithAcctPriceByCodeOrName(product);
                if (prodList.size() == 0) {
                    nameList.add(i + 2);
                }

            }
        }
        if (addrList.size() > 0) {
            String suoyin = "";
            for (int n : addrList) {
                suoyin += (n + " ");
            }
            errorMessage += "Excel第" + suoyin + "行地址信息有误；";
        }
        if (dateList.size() > 0) {
            String suoyin = "";
            for (int n : dateList) {
                suoyin += (n + " ");
            }
            errorMessage += "Excel第" + suoyin + "行日期格式有误；";
        }
        if (codeList.size() > 0) {
            String suoyin = "";
            for (int n : codeList) {
                suoyin += (n + " ");
            }
            errorMessage += "Excel第" + suoyin + "行产品编码信息有误；";
        }
        if (nameList.size() > 0) {
            String suoyin = "";
            for (int n : nameList) {
                suoyin += (n + " ");
            }
            errorMessage += "Excel第" + suoyin + "行产品名称信息有误；";
        }
        if (!"".equals(errorMessage)) {
            throw new Exception(errorMessage);
        }
    }

    @Override
    public void importHeadAndItemExcel(List<OrderImpExp> list, HttpServletRequest request) throws Exception {
        Map<String, String> map = new HashMap<String, String>();
        Enterprise enterprise = (Enterprise) (request.getSession().getAttribute("UserEnterpriseContext"));
        String multiPriceList = enterprise.getIsMultiPriceList();
        //String noOther = "";//存放只有一个产品的订单list序号
        for (int i = 0; i < list.size(); i++) {
            //获取订单编码
            String key = list.get(i).getOrderNo();
            String old = map.get(key);
            if (old != null) {
                map.put(key, old + "," + (i));
            } else {
                map.put(key, "" + (i));
            }
        }
        Iterator<String> it = map.keySet().iterator();
        while (it.hasNext()) {
            String key = it.next();
            String value = map.get(key);
            System.out.println(key + " 重复,行： " + value);
            String[] a = value.split(",");
            //合并客户名相同的为一个订单
            //acctName,payType,addr,expectDate,comments,prodCode,qty
            //orderNo,addr,comments,prodCode,prodName,qty
            OrderImpExp orderImpExp = new OrderImpExp();
            orderImpExp = list.get(Integer.parseInt(a[0]));

            //根据当前登陆用户客户ID获取组织ID
            CoreUser user = UserUtil.getUser();
            Account account = new Account();
            account.setId(user.getAcctId());
            account = accountMapper.queryById(account);

            //根据地址名找客户地址ID
            QueryParams qps = new QueryParams();
            qps.addFilter(new Filter("fullAddr", String.valueOf(orderImpExp.getAddr())));
            qps.addFilter(new Filter("acctId", String.valueOf(user.getAcctId())));
            qps.setPageFlag(false);
            AcctAddress acctAddr = (AcctAddress) BasicModel.transformClass(AcctAddress.class, qps);
            List<AcctAddress> acctAddrList = acctAddressMapper.queryByExamplePage(acctAddr);
            if (acctAddrList.size() == 0) {
                throw new ServiceException("ORDER-091");
            }
            acctAddr = acctAddrList.get(0);

            //订单号不为空时设置，所有订单编号为空的商品合并为同一个订单
            if (!"".equals(orderImpExp.getOrderNo())) {
                //saleOrder.setOrderNo(orderImpExp.getOrderNo());//订单编号
            }
            SaleOrder saleOrder = new SaleOrder();
            //订单ID
            saleOrder.setId(keyGenerateService.keyGenerate());
            //期望发货时间
            saleOrder.setExpectDate(orderImpExp.getExpectDate());
            //客户ID
            saleOrder.setAcctId(user.getAcctId());
            //saleOrder.setPayType(orderImpExp.getPayType());
            // 地址ID
            saleOrder.setAddrId(acctAddr.getId());
            //省
            saleOrder.setProvince(acctAddr.getProvince());
            //市
            saleOrder.setCity(acctAddr.getCity());
            //县
            saleOrder.setDistrict(acctAddr.getDistrict());
            //具体地址
            saleOrder.setCustomAddr(acctAddr.getAddr());
            //收货联系人
            saleOrder.setCustomConsignee(acctAddr.getConsignee());
            //收货联系电话
            saleOrder.setCustomMobilePhone(acctAddr.getMobilePhone());
            //订单备注（头）
            saleOrder.setComments(orderImpExp.getComments());
            saleOrder.setOrderType("销售订单");
            saleOrder.setStatus("Submitted");
            saleOrder.setOrgId(account.getOrgId());
            //插入头信息
            saleOrderService.insert(saleOrder);
            for (int i = 0; i < a.length; i++) {
                int b = Integer.parseInt(a[i]);
                SaleOrderItem saleOrderItem = new SaleOrderItem();
                orderImpExp = list.get(b);
                //设置头ID
                saleOrderItem.setHeadId(saleOrder.getId());
                //根据产品编码或商品名称找产品ID
                if (!"".equals(orderImpExp.getProdCode())) {
                    Product product = new Product();
                    product.setPageFlag(false);
                    product.setProdCode(orderImpExp.getProdCode());
                    product.setAcctId(user.getAcctId());

                    product.setAttr7(multiPriceList);

                    List<Product> prodList = productMapper.queryProdWithAcctPriceByCodeOrName(product);
                    if (prodList.size() >= 1) {
                        //找到一个或多个产品信息时取第一条生成行，没找到忽略当条
                        //throw new Exception("产品编码信息有误！");
                        product = prodList.get(0);
                        saleOrderItem.setProdId(product.getId());
                        saleOrderItem.setQty(orderImpExp.getQty());
                        //原价
                        saleOrderItem.setBasePrice(product.getPrice());
                        //促销价
                        saleOrderItem.setPromotionPrice(product.getPromoPrice());
                        //实际价格
                        saleOrderItem.setNetPrice(product.getPromoPrice());
                        //将Excel订单编号写入行备注
                        saleOrderItem.setProdComments(orderImpExp.getOrderNo());
                        saleOrderItemService.insert(saleOrderItem);
                    }
                } else if (!"".equals(orderImpExp.getProdName())) {
                    Product product = new Product();
                    product.setPageFlag(false);
                    product.setProdName(orderImpExp.getProdName());
                    product.setAcctId(user.getAcctId());

                    product.setAttr7(multiPriceList);

                    List<Product> prodList = productMapper.queryProdWithAcctPriceByCodeOrName(product);
                    if (prodList.size() >= 1) {
                        //throw new Exception("产品名称信息有误！");
                        product = prodList.get(0);
                        saleOrderItem.setProdId(product.getId());
                        saleOrderItem.setQty(orderImpExp.getQty());
                        //原价
                        saleOrderItem.setBasePrice(product.getPrice());
                        //促销价
                        saleOrderItem.setPromotionPrice(product.getPromoPrice());
                        //实际价格
                        saleOrderItem.setNetPrice(product.getPromoPrice());
                        //将Excel订单编号写入行备注
                        saleOrderItem.setProdComments(orderImpExp.getOrderNo());
                        saleOrderItemService.insert(saleOrderItem);
                    }

                }
            }

        }
    }

    @RequestMapping({"/importExcel"})
    @ResponseBody
    @Transactional(
            rollbackFor = {BasicControllerException.class}
    )
    public Map<String, Object> importExcel(OrderImpExp entity, QueryParams qps, HttpSession session,
                                           HttpServletRequest request, HttpServletResponse response) {

        Map<String, Object> result = new HashMap();
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
        MultipartFile file = multipartRequest.getFile("file");
        CommonsMultipartFile cf = (CommonsMultipartFile)file;
        DiskFileItem fi = (DiskFileItem)cf.getFileItem();
        File tempFile = fi.getStoreLocation();
        String isCheck = multipartRequest.getParameter("isCheck");
        String fileName = file.getOriginalFilename();
        String fileext = fileName.substring(fileName.lastIndexOf("."), fileName.length());
        fileext = fileext.toLowerCase();
        new ArrayList();
        String fieldNames = "";
        int sheetNo = 0;
        boolean hasTitle = false;
        boolean isHeadAndItem = false;

        try {
            this.beforReadExcel(entity, qps, request);
            fieldNames = qps.getAttr1();
            if (qps.getAttr2() != null) {
                sheetNo = Integer.parseInt(qps.getAttr2());
            }

            if (qps.getAttr3() != null) {
                hasTitle = Boolean.parseBoolean(qps.getAttr3());
            }

            if (qps.getAttr4() != null) {
                isHeadAndItem = Boolean.parseBoolean(qps.getAttr4());
            }

            List list;
            String[] fieldNamess;
            if (".xls".equals(fileext)) {
                HssfExcelHelper excel2003 = HssfExcelHelper.getInstance(tempFile);
                fieldNamess = fieldNames.split(",");
                list = excel2003.readExcel(entity.getClass(), fieldNamess, sheetNo, hasTitle);
            } else {
                if (!".xlsx".equals(fileext)) {
                    throw new ServiceException("PUBLIC-057");
                }

                XssfExcelHelper excel2007 = XssfExcelHelper.getInstance(tempFile);
                fieldNamess = fieldNames.split(",");
                list = excel2007.readExcel(entity.getClass(), fieldNamess, sheetNo, hasTitle);
            }

            if ("true".equals(isCheck)) {
                this.importCheckExcel(list, request);
            } else if (isHeadAndItem) {
                this.importHeadAndItemExcel(list, request);
            } else {
                for (int i = 0; list != null && i < list.size(); ++i) {
                    OrderImpExp record = (OrderImpExp)list.get(i);
                    this.beforeImportExcel(record, request);
                    this.getBasicService().insert(record);
                }
            }

            if (list == null) {
                result.put("success", true);
                result.put("total", 0);
            } else {
                result.put("success", true);
                result.put("total", list.size());
            }
        } catch (BasicServiceException var22) {
            logger.error("BasicController捕获异常: ", var22);
            result.put("success", false);
            result.put("result", var22.getMessage());
            result.put("detailMessage", var22.getDetailMessage());
        } catch (Exception var23) {
            logger.error("BasicController捕获异常: ", var23);
            result.put("success", false);
            result.put("result", var23.getMessage());
        }

        return result;
    }
}
